package com.jf.nep.render;

import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector4f;

public class Vertex {
    /** The number of bytes for each element in a vertex */
    public static final int ELEMENT_BYTE_SIZE = 4;
    
    /** Number of elements to store position */
    public static final int POS_ELEMENT_COUNT = 4;
        
    /** Number of elements to store normal */
    public static final int NORM_ELEMENT_COUNT = 4;
    
    /** Number of elements to store texture coordinate */
    public static final int TEX_ELEMENT_COUNT = 2;

    /** Offset in elements of position */
    public static final int POS_ELEMENT_OFFSET = 0;
    
    /** Offset in elements of normal */
    public static final int NORM_ELEMENT_OFFSET = POS_ELEMENT_OFFSET + POS_ELEMENT_COUNT;
    
    /** Offset in elements of texture coord */
    public static final int TEX_ELEMENT_OFFSET = NORM_ELEMENT_OFFSET + NORM_ELEMENT_COUNT;
    
    /** Total element count to store a vertex */
    public static final int TOTAL_COUNT =  POS_ELEMENT_COUNT + NORM_ELEMENT_COUNT + TEX_ELEMENT_COUNT;
    
    /** The stride i.e. how many bytes a vertex occupies */
    public static final int BYTE_SIZE = TOTAL_COUNT * ELEMENT_BYTE_SIZE;
    
    /** An array of offsets for the element types in a vertex */
    public static final int ELEMENT_OFFSETS[] = new int[] {
        POS_ELEMENT_OFFSET,
        NORM_ELEMENT_OFFSET,
        TEX_ELEMENT_OFFSET        
    };
    
    /** Attribute name in the shader corresponding to the vertex data */
    public static final String SHADER_ATTRIBUTES[] = new String[] {
        "in_Position",
        "in_Normal",
        "in_TextureCoord"
    };
    
    public static final int BYTE_OFFSETS[] = new int[] {
        ELEMENT_OFFSETS[0] * ELEMENT_BYTE_SIZE,
        ELEMENT_OFFSETS[1] * ELEMENT_BYTE_SIZE,
        ELEMENT_OFFSETS[2] * ELEMENT_BYTE_SIZE,
    };    
    
    public static final int ELEMENT_COUNTS[] = new int[] {
        POS_ELEMENT_COUNT,
        NORM_ELEMENT_COUNT,
        TEX_ELEMENT_COUNT
    };
    
    /** Number of element types contained within a vertex */
    public static final int NUMBER_OF_ELEMENT_TYPES = ELEMENT_OFFSETS.length;
    
    public Vector4f pos;
    public Vector2f tex;
    public Vector4f norm;
    
    private float[] vertexArray = new float[TOTAL_COUNT];

    public Vertex(Vector4f pos) {
        this.pos = pos;
        this.tex = new Vector2f(0,0);
        this.norm = new Vector4f(0,1,0,1);
        store();
    }

    public Vertex(Vector4f pos, Vector4f norm) {
        this.pos = pos;
        this.tex = new Vector2f(0,0);
        this.norm = norm;
        store();
    }

    public Vertex(Vector4f pos, Vector4f norm, Vector2f tex) {
        this.pos = pos;
        this.tex = tex;
        this.norm = norm;
        store();
    }
    
    public float[] getArray() {
        return vertexArray;
    }
    
    
    private void store() {
        vertexArray[POS_ELEMENT_OFFSET] = pos.x;
        vertexArray[POS_ELEMENT_OFFSET+1] = pos.y;
        vertexArray[POS_ELEMENT_OFFSET+2] = pos.z;
        vertexArray[POS_ELEMENT_OFFSET+3] = pos.w;
        vertexArray[NORM_ELEMENT_OFFSET] = norm.x;
        vertexArray[NORM_ELEMENT_OFFSET+1] = norm.y;
        vertexArray[NORM_ELEMENT_OFFSET+2] = norm.z;
        vertexArray[NORM_ELEMENT_OFFSET+3] = norm.w;
        vertexArray[TEX_ELEMENT_OFFSET] = tex.x;
        vertexArray[TEX_ELEMENT_OFFSET+1] = tex.y;
        
        System.out.println("Vertex: ");
        for (int i = 0; i < vertexArray.length; i++) {
            System.out.print(vertexArray[i]+" ");
        }
        System.out.println();
    }
    
}
